package com.atguigu.virtual;

class MyClass{
    public void method(Father f) {
        System.out.println("father");
    }
    public void method(Son s) {
        System.out.println("son");
    }
}
class MySub extends MyClass{
    public void method(Father d) {
        System.out.println("sub--father");
    }
    public void method(Daughter d) {
        System.out.println("daughter");
    }
}
class Father{

}
class Son extends Father{

}
class Daughter extends Father{

}
public class TestVirtualMethod {
    public static void main(String[] args) {
        Father f = new Father();
        Son s = new Son();
        Daughter d = new Daughter();

        MyClass my = new MySub(); //多态引用
        my.method(f);//调用虚方法method。运行结果是sub--father
        /*
        （1）编译时看左边（父类）
        my是MyClass类型，就在MyClass类中找可以匹配的方法。
        f是实参，它是Father类型，它与哪个method方法的形参更匹配。
        public void method(Father f) {
            System.out.println("father");
        }

        （2）运行时看右边（子类）
        my的=右边new的是MySub的对象，就要看MySub类中是否有对刚刚匹配的方法进行了重写。
        如果有，就执行重写后的。如果没有就仍然执行刚刚匹配的方法。
        这里有重写
         public void method(Father d) {
            System.out.println("sub--father");
        }
        执行重写后的。
         */

        my.method(s);//调用虚方法method。运行结果是son
        /*
        （1）编译时看左边（父类）
        my是MyClass类型，就在MyClass类中找可以匹配的方法。
        s是实参，它是Son类型，它与哪个method方法的形参更匹配。
        public void method(Son s) {
            System.out.println("son");
        }

        （2）运行时看右边（子类）
        my的=右边new的是MySub的对象，就要看MySub类中是否有对刚刚匹配的方法进行了重写。
        如果有，就执行重写后的。如果没有就仍然执行刚刚匹配的方法。
        这里没有重写

        执行在父类中匹配的方法。
         */

        my.method(d);//调用虚方法method。运行结果是
        /*
        （1）编译时看左边（父类）
        my是MyClass类型，就在MyClass类中找可以匹配的方法。
        d是实参，它是Daughter类型，它与哪个method方法的形参更匹配。没有最匹配的，但是可以找到兼容的。
        public void method(Father f) {
            System.out.println("father");
        }

        （2）运行时看右边（子类）
        my的=右边new的是MySub的对象，就要看MySub类中是否有对刚刚匹配的方法进行了重写。
        如果有，就执行重写后的。如果没有就仍然执行刚刚匹配的方法。
        这里有重写
         public void method(Father d) {
            System.out.println("sub--father");
        }
        执行重写后的。
         */

        Father b = new Son();
        my.method(b);//调用虚方法method。运行结果
        /*
        （1）编译时看左边（父类）
        my是MyClass类型，就在MyClass类中找可以匹配的方法。
        b是实参，它是Father类型（编译是Father），它与哪个method方法的形参更匹配。
        public void method(Father f) {
            System.out.println("father");
        }

        （2）运行时看右边（子类）
        my的=右边new的是MySub的对象，就要看MySub类中是否有对刚刚匹配的方法进行了重写。
        如果有，就执行重写后的。如果没有就仍然执行刚刚匹配的方法。
        这里有重写
         public void method(Father d) {
            System.out.println("sub--father");
        }
        执行重写后的。
         */
    }
}

